#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
#include<string>
//int main()
//{
//	string s1("xxxxxx");
//	cout << s1 << endl;
//	cout << s1.c_str() << endl;
//	cin >> s1;
//	cout << s1.c_str() << endl;
//
//
//	return 0;
//}

#include <iostream>
#include <assert.h>
using namespace std;

namespace chaos
{
	class string {
	public:
		/* 构造函数 */
		string(const char* str = "")
			: _size(strlen(str))        // 计算出字符串str的大小
			, _capacity(_size) {        // 初始容量等于字符串大小

			_str = new char[_capacity + 1];   // 开辟一块 "容量+1" 大小的空间 (_capacity存的是有效字符）
			strcpy(_str, str);                // 将传入的字符串str复制到 _str中
		}

		void Swap(string& tmp) {
			swap(_str, tmp._str);
			swap(_size, tmp._size);
			swap(_capacity, tmp._capacity);
		}

		/* 拷贝构造函数：s2(s1)
		string(const string& src)
			: _size(src._size)                // 拷贝string大小
			, _capacity(src._capacity) {      // 拷贝string容量
			// 拷贝string内容
			_str = new char[src._capacity + 1];        // 开辟一块和src相同容量的空间
			strcpy(_str, src._str);					   // 将src中的_str内容拷贝到自己的_str中
		}
		*/
		string(const string& src)
			: _str(nullptr)
			, _size(0)
			, _capacity(0) {

			string tmp(src._str);   // 拷贝构造一个src
			Swap(tmp);              // 现代写法：交换
		}


		/* 赋值重载：s1 = s3
		string& operator=(const string& src) {
			// 防止自己跟自己赋值
			if (this != &src) {
				// 1. 暂时用tmp开辟一块相同的空间
				char* tmp = new char[src._capacity + 1];
				// 2. 把src的值复制给tmp
				strcpy(tmp, src._str);
				// 3. 释放this原空间
				delete[] _str;
				// 4. 没翻车，把tmp交付给_src
				_str = tmp;
				_size = src._size;
				_capacity = src._capacity;
			}
			return *this;
		}
		string& operator=(const string& src) {
			// 防止自己跟自己赋值
			if (this != &src) {
				string tmp(src);   // 复用拷贝构造
				Swap(tmp);
			}
			return *this;
		}
		*/
		string& operator=(string src) {
			Swap(src);    // 正好调用拷贝构造，不如让形参充当tmp
			return *this;
		}


		/* 返回C格式的字符串：c_str */
		const char* c_str() const {
			return _str;
		}

		/* 求字符串大小：size() */
		size_t size() const {
			return _size;
		}

		/* operator[] */
		char& operator[](size_t pos) {
			assert(pos < _size);
			return _str[pos];  // 返回字符串对应下标位置的元素
		}
		const char& operator[](size_t pos) const {
			assert(pos < _size);
			return _str[pos];
		}

		/* 迭代器 */
		typedef char* iterator;
		iterator begin() {
			return _str;            // 返回第一个字符的位置
		}
		iterator end() {
			return _str + _size;    // 返回最后一个字符的位置
		}

		/* const迭代器 */
		typedef const char* const_iterator;
		const_iterator begin() const {
			return _str;
		}
		const_iterator end() const {
			return _str + _size;
		}

		/* reserve() */
		void reserve(size_t new_capacity) {
			if (new_capacity > _capacity) {               // 检查是否真的需要扩容
				char* tmp = new char[new_capacity + 1];   // 开空间
				strcpy(tmp, _str);						  // 先搬运数据到tmp

				_str = tmp;								  // 没翻车，递交给_str
				_capacity = new_capacity;				  // 更新容量
			}
		}

		/* 字符尾插：push_back() */
		void push_back(char append_ch) {
			/*
			if (_size == _capacity) {                         // 检查是否需要扩容
				reserve(_capacity == 0 ? 4 : _capacity * 2);  // 首次给4，其他情况默认扩2倍
			}
			_str[_size] = append_ch;     // 插入要追加的字符
			_size++;
			_str[_size] = '\0';	         // 手动添加'\0'
			*/

			insert(_size, append_ch);
		}

		/* 字符串追加：append() */
		void append(const char* append_str) {
			/*
			size_t len = strlen(append_str);      // 计算出要追加的字符串的长度
			if (_size + len > _capacity) {		  // 检查是否需要扩容
				reserve(_size + len);
			}
			strcpy(_str + _size, append_str);      // 首字符+大小，就是'\0'位置
			_size += len;						   // 更新大小
			*/

			insert(_size, append_str);
		}

		/* operator+= */
		string& operator+=(char append_ch) {
			push_back(append_ch);
			return *this;
		}
		string& operator+=(const char* append_str) {
			append(append_str);
			return *this;
		}

		/* insert */
		string& insert(size_t pos, char append_ch) {
			assert(pos <= _size);

			if (_size == _capacity) {		// 检查是否需要扩容
				reserve(_capacity == 0 ? 4 : _capacity * 2);
			}

			// 向后挪动数据
			size_t end = _size + 1;
			while (end > pos) {
				_str[end] = _str[end - 1];
				end--;
			}

			// 插入
			_str[pos] = append_ch;
			_size++;

			return *this;
		}
		string& insert(size_t pos, const char* append_str) {
			assert(pos <= _size);
			size_t len = strlen(append_str);

			if (_size + len > _capacity) {    // 检查是否需要增容
				reserve(_size + len);
			}

			// 向后挪动数据
			size_t end = _size + len;
			while (end > pos + len - 1) {
				_str[end] = _str[end - len];
				end--;
			}

			// 插入
			strncpy(_str + pos, append_str, len);
			_size += len;

			return *this;
		}

		/* resize */
		void resize(size_t new_capacity, char init_ch = '\0') {
			// 如果欲增容量比_size小
			if (new_capacity <= _size) {
				_str[new_capacity] = '\0';      // 拿斜杠零去截断
				_size = new_capacity;           // 更新大小
			}
			// 欲增容量比_size大
			else {
				if (new_capacity > _capacity) {
					reserve(new_capacity);
				}
				// 起始位置，初始化字符，初始化个数
				memset(_str + _size, init_ch, new_capacity - _size);
				_size = _capacity;
				_str[_size] = '\0';
			}
		}

		/* find */
		size_t find(char aim_ch) {
			for (size_t i = 0; i < _size; i++) {
				if (aim_ch == _str[i]) {
					// 找到了
					return i;    // 返回下标
				}
			}
			// 找不到
			return npos;
		}
		size_t find(const char* aim_str, size_t pos = 0) {
			const char* ptr = strstr(_str + pos, aim_str);
			if (ptr == nullptr) {
				return npos;
			}
			else {
				return ptr - _str;  // 减开头
			}
		}

		/* 删除：erase */
		string& erase(size_t pos, size_t len = npos) {
			assert(pos < _size);

			if (len == pos || pos + len >= _size) {
				_str[pos] = '\0';    // 放置\0截断
				_size = pos;
			}
			else {
				strcpy(_str + pos, _str + pos + len);
				_size -= len;
			}

			return *this;
		}

		/* 析构函数 */
		~string() {
			if (_str != nullptr) {
				delete[] _str;
				_str = nullptr;
			}
			_size = _capacity = 0;
		}

	private:
		/* 成员变量 */
		char* _str;
		size_t _size;
		size_t _capacity;

	public:
		static const size_t npos;
	};

	/* 初始化npos */
	const size_t string::npos = -1;   // 无符号整型的-1，即整型最大值

	/* s1 < s2*/
	bool operator<(const string& s1, const string& s2) {
		/*
		size_t i1 = 0, i2 = 0;
		while (i1 < s1.size() && i1 < s2.size()) {
			if (s1[i1] < s2[i2]) {
				return true;
			}
			else if (s1[i1] > s2[i2]) {
				return false;
			}
			else {
				i1++;
				i2++;
			}
		}
		return i2 < s2.size() ? true : false;
		*/

		return strcmp(s1.c_str(), s2.c_str()) < 0;
	}

	/* s1 == s2 */
	bool operator==(const string& s1, const string& s2) {
		return strcmp(s1.c_str(), s2.c_str()) == 0;
	}

	/* s1 <= s2 */
	bool operator<=(const string& s1, const string& s2) {
		return s1 < s2 || s1 == s2;
	}

	/* s1 > s2 */
	bool operator>(const string& s1, const string& s2) {
		return !(s1 <= s2);
	}

	/* s1 >= s2 */
	bool operator>=(const string& s1, const string& s2) {
		return !(s1 < s2);
	}


	/* s1 != s2 */
	bool operator!=(const string& s1, const string& s2) {
		return !(s1 == s2);
	}

	// cout << s1  →  operator<<(cout, s1)
	ostream& operator<<(ostream& out, const string& s) {
		/*
		for (auto ch : s) {
			out << ch;
		}
		*/

		for (size_t i = 0; i < s.size(); i++) {
			out << s[i];
		}

		return out;
	}

	// cin >>
	istream& operator<<(istream& in, string& s) {
		char ch = in.get();
		while (ch == '\n') {
			s += ch;
			ch = in.get();
		}

		return in;
	}



	/* 测试用 */
	void test_string1() {
		string s1("hello world");
		string s2(s1);
		cout << s1.c_str() << endl;
		cout << s2.c_str() << endl;

		string s3("pig");
		cout << s3.c_str() << endl;

		s1 = s3;
		cout << s1.c_str() << endl;
	}

	void test_string2() {
		string s1("hello world");
		string s2;

		for (size_t i = 0; i < s1.size(); i++) {
			cout << s1[i] << " ";
		}
		cout << endl;
	}

	void test_string3() {
		string s1("hello world");
		string s2;

		s1[0] = 'F';
		for (size_t i = 0; i < s1.size(); i++) {
			cout << s1[i] << " ";
		}
		cout << endl;
	}

	void test_string4() {
		string s1("hello world");

		// 迭代器写
		string::iterator it = s1.begin();
		while (it != s1.end()) {
			*it += 1;
			it++;
		}

		// 迭代器读
		it = s1.begin();   // 重置起点
		while (it != s1.end()) {
			cout << *it << " ";
			it++;
		}
	}

	void test_string5() {
		string s1("hello world");
		cout << s1.c_str() << endl;

		s1.push_back('!');
		cout << s1.c_str() << endl;

		s1.push_back('A');
		cout << s1.c_str() << endl;
	}

	void test_string6() {
		string s1("hello world");
		cout << s1.c_str() << endl;

		s1 += '!';
		cout << s1.c_str() << endl;

		s1 += "this is new data";
		cout << s1.c_str() << endl;
	}

	void test_string7() {
		string s1("hello world");
		cout << s1.c_str() << endl;

		s1.insert(0, 'X');
		cout << s1.c_str() << endl;

		s1.insert(0, "hahahaha");
		cout << s1.c_str() << endl;
	}

	void test_string8() {
		string s1("hello world");
		cout << s1.c_str() << endl;

		s1.erase(5, 2);   // 从第五个位置开始，删两个字符
		cout << s1.c_str() << endl;

		s1.erase(5, 20);  // 从第五个位置开始，删完
		cout << s1.c_str() << endl;

	}
}
